fix(ci): scope pip-audit to locked deps (was failing on transient runner pip CVE) - #53
Conversation
The security job was failing on every PR because `uvx pip-audit==2.9.0` with no -r argument scans the transient uvx environment, which contains its own pip 26.0.1 — flagged by GHSA-58qw-9mgm-455v / CVE-2026-3219 (pip tar/ZIP interpretation conflict, severity medium, no patched version available yet). pip is not in our uv.lock; this audit was auditing the runner's Python environment, not our actual deps. Fix: export uv.lock to a requirements.txt and pass it via -r. Audits exactly our pinned dependencies, ignores the transient runner pip. Stderr is dropped because `uv export` writes 'Resolved 36 packages' to stderr which would land at line 1 of the file via shell redirection on some setups and trip pip-audit's parser. Verified locally: 'No known vulnerabilities found' against current uv.lock. Will keep working when upstream eventually patches pip; still correctly fails CI if any of OUR pinned deps gain a new vuln.
Review Summary by QodoScope pip-audit to locked dependencies, fix runner CVE false positive
WalkthroughsDescription• Scope pip-audit to locked dependencies via uv export • Prevents false positives from runner's transient pip environment • Redirects uv export stderr to avoid parser issues • Ensures audit only checks project's pinned dependencies Diagramflowchart LR
A["uv.lock"] -->|"uv export"| B["requirements.txt"]
B -->|"-r flag"| C["pip-audit 2.9.0"]
C -->|"scans only"| D["Project dependencies"]
E["Runner pip 26.0.1"] -.->|"ignored"| C
File Changes1. .github/workflows/tests.yml
|
Code Review by Qodo
1. Disallowed .github/ path modified
|
✅ Grippy Review — PASSScore: 100/100 | Findings: 0 Commit: 62033e4 |
There was a problem hiding this comment.
Pull request overview
Adjusts the CI dependency-audit step to scan only this repository’s locked dependencies (via uv.lock), avoiding false positives caused by vulnerabilities in the transient tool/runtime environment on GitHub-hosted runners.
Changes:
- Export the resolved
uv.lockdependency tree to a requirements file usinguv export. - Run
pip-auditagainst that exported requirements file (pip-audit -r ...) instead of auditing the transientuvxenvironment.
| # for GHSA-58qw-9mgm-455v / CVE-2026-3219, an unpatched pip CVE | ||
| # that has nothing to do with this project's dependencies). | ||
| run: | | ||
| uv export --format requirements.txt --no-emit-project --no-hashes > /tmp/audit-deps.txt 2>/dev/null |
There was a problem hiding this comment.
uv export ... 2>/dev/null suppresses all stderr, which will hide real export errors/warnings and make CI failures much harder to debug (you'll just see a downstream pip-audit failure). Prefer keeping stderr visible, or suppress only the known benign progress line (e.g., via a --quiet/--no-progress flag if uv export supports it, or by filtering that specific line while still surfacing errors).
| uv export --format requirements.txt --no-emit-project --no-hashes > /tmp/audit-deps.txt 2>/dev/null | |
| uv export --format requirements.txt --no-emit-project --no-hashes > /tmp/audit-deps.txt |
| # Scope the audit to OUR locked dependency tree exported from uv, | ||
| # not the transient uvx environment. Otherwise pip-audit also scans | ||
| # its own runtime (which currently flags the runner's pip 26.0.1 | ||
| # for GHSA-58qw-9mgm-455v / CVE-2026-3219, an unpatched pip CVE | ||
| # that has nothing to do with this project's dependencies). | ||
| run: | | ||
| uv export --format requirements.txt --no-emit-project --no-hashes > /tmp/audit-deps.txt 2>/dev/null | ||
| uvx pip-audit==2.9.0 -r /tmp/audit-deps.txt |
There was a problem hiding this comment.
1. Disallowed .github/ path modified 📘 Rule violation § Compliance
This PR modifies .github/workflows/tests.yml, which is outside the allowed top-level directories (src/, tests/, packs/, docs/) and no explicit approval is recorded. This violates the directory allow-list policy for file modifications.
Agent Prompt
## Issue description
A file outside the allowed directory prefixes was modified without an explicit approval note.
## Issue Context
Policy allow-lists modifications to `src/`, `tests/`, `packs/`, `docs/` unless an explicit approval/exception is recorded in the PR.
## Fix Focus Areas
- .github/workflows/tests.yml[169-176]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Summary
The
securityjob intests.ymlis failing on every PR right now becauseuvx pip-audit==2.9.0(with no-rargument) audits its own transient uvx environment, which contains the runner'spip 26.0.1— flagged by GHSA-58qw-9mgm-455v / CVE-2026-3219 (pip tar/ZIP interpretation conflict, severity medium, no patched version available).pipis not in ouruv.lock— this audit was scanning the runner's Python environment, not our actual dependencies.Fix
Export the resolved lockfile to a requirements file via
uv exportand pass it to pip-audit with-r. Audits exactly our pinned tree, ignores the transient uvx pip.Stderr from
uv exportis redirected to/dev/nullbecause it writesResolved 36 packages in N mswhich would otherwise land at line 1 of the requirements file under shell redirection and trip pip-audit's parser.Test plan
uv export ... 2>/dev/null > /tmp/req.txt && uvx pip-audit==2.9.0 -r /tmp/req.txt→ "No known vulnerabilities found"yaml.safe_loadsecuritystep turns green on this PR<PACK>placeholders, harden path traversal checks, strengthen empty-list tests #52 (currently blocked by this same failure) rebase and unblockWhy this is the right fix (not just
--ignore-vuln)Adding
--ignore-vuln GHSA-58qw-9mgm-455vwould temporarily silence this specific advisory but leave the broader bug — auditing the runner's Python env instead of our project. When the next runner-image pip CVE drops we'd need another ignore. Scoping to our actual deps is the durable fix.